package com.m3958.logcollector.datacommons.controller;

import java.io.IOException;
import java.io.InputStream;
import java.nio.file.Path;
import java.nio.file.Paths;
import java.util.UUID;

import javax.servlet.http.HttpServletRequest;

import org.apache.commons.fileupload.FileItemIterator;
import org.apache.commons.fileupload.FileItemStream;
import org.apache.commons.fileupload.FileUploadException;
import org.apache.commons.fileupload.servlet.ServletFileUpload;
import org.apache.commons.fileupload.util.Streams;
import org.slf4j.Logger;
import org.slf4j.LoggerFactory;
import org.springframework.beans.factory.annotation.Autowired;
import org.springframework.stereotype.Controller;
import org.springframework.web.bind.annotation.ExceptionHandler;
import org.springframework.web.bind.annotation.RequestHeader;
import org.springframework.web.bind.annotation.RequestMapping;
import org.springframework.web.bind.annotation.RequestMethod;
import org.springframework.web.bind.annotation.ResponseBody;

import com.m3958.logcollector.datacommons.util.UploadConfig;
import com.m3958.logcollector.datacommons.util.UploadUtil;


@Controller
public class UploadController {

	private Logger logger = LoggerFactory.getLogger(this.getClass());

	@Autowired(required = false)
	private UploadConfig uploadConfig;

	@ExceptionHandler(Exception.class)
	@ResponseBody
	public UploadResult handleIOException(Exception ex) {
		return new UploadResult(ex.getMessage());
	}

	@RequestMapping(value = "/upload", method = RequestMethod.POST)
	@ResponseBody
	public UploadResult upload(HttpServletRequest request, @RequestHeader(value = "content-length", required = false, defaultValue = "-1") long contentLength) {
		boolean isMultipart = ServletFileUpload.isMultipartContent(request);
		logger.info(request.getHeader("content-type"));
		if (contentLength > uploadConfig.getMultipartMaxRequestSize()) {
			return new UploadResult("TOO_BIG");
		}

		logger.info("content length: {}", contentLength);
		
		Path uploadDestFolder = Paths.get(uploadConfig.getUploadDestFolder());

		if (!isMultipart) {
			return new UploadResult("NOT_MULTIPART");
		}

		ServletFileUpload upload = new ServletFileUpload();
		try {
			FileItemIterator iter = upload.getItemIterator(request);
			while (iter.hasNext()) {
				FileItemStream item = iter.next();
				String name = item.getFieldName();
				InputStream stream = item.openStream();
				
				if (item.isFormField()) {
					logger.info("Form field {} with value {} detected.", name, Streams.asString(stream));
				} else {
					UploadUtil.copyToFile(stream, uploadDestFolder.resolve(UUID.randomUUID().toString()), -1);
				}
			}
		} catch (FileUploadException e) {
			return new UploadResult("FileUploadException");
		} catch (IOException e) {
			return new UploadResult("IOException");
		} catch (Exception ee) {
			return new UploadResult("Exception");
		}
		return new UploadResult(true);
	}

	@RequestMapping(value = "/upload", method = RequestMethod.GET)
	public String uploadGet() {
		return "upload";
	}

	public static class UploadResult {
		private boolean success;

		private String message;

		public UploadResult() {
		}

		public UploadResult(boolean success) {
			this.setSuccess(success);
		}

		public UploadResult(String message) {
			this.setSuccess(false);
			this.setMessage(message);
		}

		public boolean isSuccess() {
			return success;
		}

		public void setSuccess(boolean success) {
			this.success = success;
		}

		public String isMessage() {
			return message;
		}

		public void setMessage(String message) {
			this.message = message;
		}
	}
}
